﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

// Reviewed
#pragma once
#include "GcmpModelInterface.h"
#include <string>
#include "ParameterProcessType.h"
#include "ParameterStorageType.h"
#include "ParameterUnitType.h"
#include "ParameterDisplayType.h"
#include "GcmpApiDeclaration.h"
#include "IObject.h"
#include "GcmpApiDeclaration.h"
#include "ParameterStandardType.h"

namespace gcmp
{
    class IDocument;
    class IParameterValueList;
    class UniIdentity;

    /// \brief 参数定义类
    FINAL_INTERFACE class GCMP_MODEL_INTERFACE_EXPORT IParameterDefinition
    {
        DEFINE_CAST_BASE(gcmp::IParameterDefinition)
    public:
        /// \brief 析构函数
        virtual ~IParameterDefinition(){}

        /// \brief 根据给定数据创建一个参数定义数据对象
        ///
        /// \param uid                   跨文档唯一Id
        /// \param name               参数定义数据名字
        /// \param groupName          参数分组名字
        /// \param description        参数定义数据描述
        /// \param paramStorageType   参数定义数据存储类型
        /// \param unitTypeId         参数定义数据单位类型
        /// \param parameterTypeId    参数定义数据参数类型
        /// \return 参数定义数据
        static OwnerPtr<IParameterDefinition> CreateParameterDefinition(
            const UniIdentity& uid,
            const std::wstring& name,
            const std::wstring& groupName,
            const std::wstring& description,
            ParameterStorageType parameterStorageType,
            const UniIdentity& unitTypeId,
            const UniIdentity& parameterTypeId);
       
        /// \brief 判断是否由标准属性创建的参数定义。
        ///
        /// \return 如果是由标准属性创建的参数定义，则返回true；否则返回false。
        virtual bool IsStandard() const = 0;

        /// \brief 创建一个无效的参数定义对象
        ///
        /// \return 无效的参数定义
        static OwnerPtr<IParameterDefinition> CreateInvalidParameterDefinition();

        /// \brief 获取参数定义的Id
        ///
        /// \return 参数定义的Id
        virtual int GetId() const = 0;

        /// \brief 获取参数定义的跨文档Uid
        ///
        /// \return 参数定义的跨文档Id
        virtual const UniIdentity& GetUid() const = 0; 

        /// \brief 获取参数定义名字
        ///
        /// \return 参数定义名字
        virtual const std::wstring& GetName() const = 0;

        /// \brief 获取参数分组的名字
        /// \return 参数分组名字
        virtual const std::wstring& GetGroupName() const = 0;

        /// \brief 获取参数定义描述
        ///
        /// \return 参数定义描述
        virtual const std::wstring& GetDescription() const = 0;

        /// \brief 获取参数定义存储类型
        ///
        /// \return 参数定义存储类型
        virtual ParameterStorageType GetStorageType() const = 0;

        /// \brief 获取参数定义单位类型
        ///
        /// \return 参数定义单位类型
        virtual UniIdentity GetUnitTypeId() const = 0;

        /// \brief 获取参数定义参数类型
        ///
        /// \return 参数类型
        virtual UniIdentity GetParameterTypeId() const = 0;

        /// \brief 设置参数定义名称
        ///
        /// \param name 新的名字
        /// \return bool true-设置成功， false-设置失败(名字为空)。
        virtual bool SetName(const std::wstring& name) = 0;

        /// \brief 设置参数所在分组名称
        ///
        /// \param name 新的组名字
        /// \return bool true-设置成功， false-设置失败(名字为空)。
        virtual bool SetGroupName(const std::wstring& groupName) = 0;

        /// \brief 设置参数描述信息
        ///
        /// \param desciption 描述信息
        virtual void SetDescription(const std::wstring& desciption) = 0;

        /// \brief 获取参数定义的有效性
        ///
        /// \param pDocument 文档指针
        /// \return 参数定义有效返回true，否则返回false
        virtual bool IsValidParameterDefinition(const IDocument* pDocument) const = 0;

        /// \brief 根据给定数据创建一个参数定义数据对象
        ///
        /// 参数定义的名字及描述为对应标准编码数据的名字及描述
        /// \param groupName          参数分组名字
        /// \param paramStorageType   参数定义数据存储类型
        /// \param unitTypeId         参数定义数据单位类型
        /// \param parameterTypeId    参数定义数据参数类型
        /// \return 参数定义数据
        static OwnerPtr<IParameterDefinition> CreateStandardCodeParameterDefinition(
            const std::wstring& code,
            const std::wstring& groupName,
            ParameterStorageType parameterStorageType,
            const UniIdentity& unitTypeId,
            const UniIdentity& parameterTypeId);

        /// \brief 获取标准编码值
        ///
        /// \return 标准编码值
        virtual const std::wstring& GetStandardCode() const = 0;

        /// \brief 克隆一个新的参数定义
        ///
        ///  新的参数定义属性与原有的保持一致， 包括uid及id
        ///
        /// \return OwnerPtr<IParameterDefinition> 返回新的参数定义
        virtual OwnerPtr<IParameterDefinition> Clone() const = 0;

        /// \brief 获取参数定义的参数值列表
        ///
        /// \return 参数值列表
        virtual const IParameterValueList* GetValueList() const = 0;

        /// \brief 获取参数编码类型
        ///
        /// \return 编码类型
        //virtual ParameterStandardType GetStandardType() const = 0;

        /// \brief 根据给定数据创建一个参数定义数据对象
        ///
        /// \param uid                   跨文档唯一Id
        /// \param name               参数定义数据名字
        /// \param groupName          参数分组名字
        /// \param description        参数定义数据描述
        /// \param paramStorageType   参数定义数据存储类型
        /// \param paramUnitType      参数定义数据单位类型
        /// \param paramDisplayType   参数定义数据显示类型
        /// \return 参数定义数据
        GCMP_OBSOLETE_API(2020/12/01, IParameterDefinition::CreateParameterDefinition(const UniIdentity&, const std::wstring&, const std::wstring&, const std::wstring&, ParameterStorageType, const UniIdentity&, const UniIdentity&)) static OwnerPtr<IParameterDefinition> CreateParameterDefinition(
            const UniIdentity& uid,
            const std::wstring& name,
            const std::wstring& groupName,
            const std::wstring& description,
            ParameterStorageType parameterStorageType,
            ParameterUnitType parameterUnitType,
            ParameterDisplayType parameterDisplayType);

        /// \brief 获取参数定义单位类型
        ///
        /// \return 参数定义单位类型
        GCMP_OBSOLETE_API(2020/12/01, IParameterDefinition::GetUnitTypeId()) virtual ParameterUnitType GetUnitType() const = 0;

        /// \brief 获取参数定义显示类型
        ///
        /// \return 参数定义显示类型
        GCMP_OBSOLETE_API(2020/12/01, IParameterDefinition::GetParameterTypeId()) virtual ParameterDisplayType GetDisplayType() const = 0;

        /// \brief 根据给定数据创建一个参数定义数据对象
        ///
        /// 参数定义的名字及描述为对应标准编码数据的名字及描述
        /// \param groupName          参数分组名字
        /// \param paramStorageType   参数定义数据存储类型
        /// \param paramUnitType      参数定义数据单位类型
        /// \param paramDisplayType   参数定义数据显示类型
        /// \return 参数定义数据
        GCMP_OBSOLETE_API(2020/12/01, IParameterDefinition::CreateStandardCodeParameterDefinition(const std::wstring&, const std::wstring&, ParameterStorageType, const UniIdentity&, const UniIdentity&)) static OwnerPtr<IParameterDefinition> CreateStandardCodeParameterDefinition(
            const std::wstring& code,
            const std::wstring& groupName,
            ParameterStorageType parameterStorageType,
            ParameterUnitType parameterUnitType,
            ParameterDisplayType parameterDisplayType);
    };

}

/// \brief 声明获取内建参数定义数据的方法
#define DEFINE_BUILT_IN_PARAMETER_DEFINITION(internalName) \
    GCMP_MODEL_EXPORT const gcmp::IParameterDefinition* GetParamDef_##internalName();

/// \brief 声明内建参数GUID
/// \param InternalName 内建参数枚举变量名
#define DECLARE_GUID(InternalName) const Guid c_guid_##InternalName

/// \brief 实现获取内建参数定义数据的方法
/// \param InternalName 内建参数枚举变量名
/// \param Name 内建参数名称
/// \param GroupName 内建参数分组名称
/// \param Description 内建参数描述信息
/// \param DebugInfo 内建参数调试信息
/// \param StorageType 内建参数存储类型
/// \param UnitType 内建参数存储数据单位类型
/// \param ParameterType 内建参数类型
#define IMPLEMENT_PD(InternalName, Name, GroupName, Description, DebugInfo, StorageType, UnitType, ParameterType) \
    const IParameterDefinition* GetParamDef_##InternalName() \
    { \
        static UniIdentity c_uid_##InternalName(c_guid_##InternalName, DebugInfo); \
        static OwnerPtr<IParameterDefinition> paramDef##InternalName = IParameterDefinition::CreateParameterDefinition(c_uid_##InternalName, Name, GroupName, Description, StorageType, UnitType, ParameterType); \
        DBG_WARN_UNLESS(paramDef##InternalName.get(), L"IParameterDefinition为空", L"GMEP", L"2019-6-21"); \
        return paramDef##InternalName.get(); \
    } \
    static BuiltInParameterDefinitionInitializer initializer_##InternalName(GetParamDef_##InternalName());  \

namespace gcmp
{
    /// \brief 内建参数初始化器，用于将定义的内建参数注册到IBuiltInParameterDefinitionManager中
    class GCMP_MODEL_INTERFACE_EXPORT BuiltInParameterDefinitionInitializer
    {
    public:
        BuiltInParameterDefinitionInitializer(const gcmp::IParameterDefinition* pPD);
    };
}



